package cn.iocoder.yudao.framework.common.util.spring;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.UtilityClass;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Map;

/**
 * Spring 工具类
 *
 * @author 芋道源码
 * @author 山野羡民（1032694760@qq.com）
 * @since 2024/12/02
 * @see cn.hutool.extra.spring.SpringUtil
 */
@SuppressWarnings({"unused"})
@UtilityClass
public class SpringUtils {
    @Setter
    @Getter
    private static ConfigurableApplicationContext applicationContext;

    public static boolean isProductionEnvironment() {
        // prod-蓝色部署环境、test-绿色部署环境
        return isProfilesActive("prod") || isProfilesActive("test");
    }

    public static boolean isDevelopmentEnvironment() {
        return isProfilesActive("dev");
    }

    public static boolean isLocalhostEnvironment() {
        return isProfilesActive("local");
    }

    public static boolean isProfilesActive(String env) {
        String profilesActive = getProperty("spring.profiles.active", env);
        return StrUtil.equalsIgnoreCase(env, profilesActive);
    }

    public static String getApplicationName() {
        String value = getProperty("spring.application.name", null);
        if (StrUtil.isNotBlank(value)) {
            return value;
        }
        return getProperty("APPLICATION_NAME", "Unknown");
    }

    public static String getProperty(String property, String defValue) {
        if (applicationContext != null) {
            return applicationContext.getEnvironment().getProperty(property, defValue);
        }
        return SpringUtil.getProperty(property, defValue);
    }

    public static <T> List<T> getBeans(Class<T> type) {
        ApplicationContext applicationContext = SpringUtil.getApplicationContext();
        if (applicationContext == null) {
            return null;
        }
        Map<String, T> map = applicationContext.getBeansOfType(type);
        if (MapUtil.isEmpty(map)) {
            return null;
        }
        return map.values().stream().toList();
    }

    public static void printHost(ApplicationStartedEvent event) {
        ApplicationContext context = event.getApplicationContext();
        String host = System.getenv("JPAAS_HOST");
        String port = System.getenv("JPAAS_HTTP_PORT");
        if (StrUtil.isBlank(port)) {
            port = System.getenv("JPAAS_HOST_PORT_8080");
        }
        if (StrUtil.isBlank(host)) {
            try {
                host = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                host = "localhost";
            }
        }
        Environment environment = context.getEnvironment();
        if (StrUtil.isBlank(port)) {
            port = environment.getProperty("local.server.port", "");
            if (StrUtil.isBlank(port)) {
                port = environment.getProperty("server.port", "8080");
            }
        }
        String contextPath = environment.getProperty("server.servlet.context-path", "/");
        @SuppressWarnings("HttpUrlsUsage")
        String url = "http://" + host + ":" + (StrUtil.isBlank(contextPath) ? port : port + contextPath);
        String endpointPath = environment.getProperty("management.endpoints.web.base-path", "/actuator");
        if (endpointPath.startsWith(contextPath)) {
            endpointPath = endpointPath.substring(contextPath.length());
        }
        System.out.print("------------------------------------------------\n");
        System.out.printf("Backend: %s%n", url);
        System.out.printf("Actuator: %s%s%n", url, endpointPath);
        System.out.printf("Public: %spublic%n", url);
        System.out.printf("Static: %sstatic%n", url);
        System.out.printf("Swagger: %sswagger-ui%n", url);
        System.out.printf("Druid: %sdruid%n", url);
        System.out.print("-------------------------------------------------\n");
    }

}
